package com.example.meijun.pantest;


import android.util.Log;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.Semaphore;


/**
 * Created by meijun on 17-4-6.
 */

public final class DownLoadManager {
    private static final String TAG = "DownLoadManager";

    /**
     * 控制下载的数量
     */

    public static int SEMAPHORE_SIZE = 2;

    private static DownLoadManager manager = null;

    //保存下载的item
    private final LinkedBlockingQueue<DownloadItem> queue;
    //保存正在下载的item
    public Map<String, ProgressDownloader> map = new HashMap<String, ProgressDownloader>(SEMAPHORE_SIZE);

    private Semaphore semaphore = new Semaphore(SEMAPHORE_SIZE);
    private Thread dispatcherThread;

    /**
     *
     */
    private Map<String, LinkedList<ProgressResponseBody.ProgressListener>> listenerMap = new HashMap<>();

    private DownLoadManager() {
        queue = new LinkedBlockingQueue<DownloadItem>();

    }

    public static DownLoadManager getInstance() {
        if (manager == null) {
            synchronized (DownLoadManager.class) {
                if (manager == null) {
                    manager = new DownLoadManager();
                }
            }

        }
        return manager;
    }


    /**
     * 添加一个下载任务
     *
     * @param item 下载对象的bean
     */
    public void addTask(DownloadItem item) {

        if (isHasTask(item)) {
            Log.i(TAG, " 队列中已经有这个 item : " + item.toString());
            return;
        }

        queue.add(item);

        if (dispatcherThread == null) {
            dispatcherThread = new Thread() {
                @Override
                public void run() {
                    executeTask();
                }
            };

            dispatcherThread.start();
        }
/*
        //此时说明线程不为空,

        if (semaphore.availablePermits() == SEMAPHORE_SIZE && !dispatcherThread.isAlive() && ! dispatcherThread.isInterrupted()) {
            // 信号量全部可以使用, 说明线程已经结束了,
            //再次启动线程去下载;
            dispatcherThread.start();

        }
*/
    }

    public boolean isHasTask(DownloadItem item) {

        boolean isHasTask = false;
        if (queue.contains(item)) {
            //如果队列中已经存在这个item 直接返回
            isHasTask = true;
        }
        isHasTask = map.containsKey(item.getUrl());
        return isHasTask;
    }

    private void executeTask() {


        DownloadItem downloadItem = null;

        try {
            while ((downloadItem = queue.take()) != null) {
                //拿到一个信号量
                semaphore.acquire();

                //拿到一个任务;
                final DownloadItem finalDownloadItem = downloadItem;
                ProgressDownloader progressDownloader = new ProgressDownloader(downloadItem.getUrl(), downloadItem.getDestination(), downloadItem.getParams(), new ProgressResponseBody.ProgressListener() {
                    @Override
                    public void onPreExecute(long contentLength) {

                        ProgressResponseBody.ProgressListener progressListener = finalDownloadItem.getProgressListener();
                        if (progressListener != null) {
                            progressListener.onPreExecute(contentLength);

                        }

                        LinkedList<ProgressResponseBody.ProgressListener> progressListeners = listenerMap.get(finalDownloadItem.getUrl());
                        if(progressListeners!=null){
                            for (ProgressResponseBody.ProgressListener p:progressListeners) {
                                p.onPreExecute(contentLength);
                            }
                        }
                    }

                    @Override
                    public void update(long totalBytes, boolean done) {
                        //任务完成后释放信号量
                        if (done) {
                            semaphore.release();
                            map.remove(finalDownloadItem.getUrl());
                            listenerMap.remove(finalDownloadItem.getUrl());
                        }

                        ProgressResponseBody.ProgressListener progressListener = finalDownloadItem.getProgressListener();
                        if (progressListener != null) {

                            progressListener.update(totalBytes, done);
                        }


                        LinkedList<ProgressResponseBody.ProgressListener> progressListeners = listenerMap.get(finalDownloadItem.getUrl());
                        if(progressListeners!=null){
                            for (ProgressResponseBody.ProgressListener p:progressListeners) {
                                p.update(totalBytes, done);
                            }
                        }
                    }

                    @Override
                    public void cancle() {

                        //如果正在下载,而此时用户取消了下载,此时也应该释放信号量并从map中移除这个progress
                        semaphore.release();
                        map.remove(finalDownloadItem.getUrl());
                        listenerMap.remove(finalDownloadItem.getUrl());
                        ProgressResponseBody.ProgressListener progressListener = finalDownloadItem.getProgressListener();
                        if (progressListener != null) {
                            progressListener.cancle();

                        }


                        LinkedList<ProgressResponseBody.ProgressListener> progressListeners = listenerMap.get(finalDownloadItem.getUrl());
                        if(progressListeners!=null){
                            for (ProgressResponseBody.ProgressListener p:progressListeners) {
                                p.cancle();
                            }
                        }
                    }


                });


                map.put(downloadItem.getUrl(), progressDownloader);

                progressDownloader.download();


            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


    }

    /**
     * 添加监听
     * 一定要注意及时在onstop方法中移除监听器
     *
     * @param url tag
     */
    public void addTaskListener(String url, ProgressResponseBody.ProgressListener listener) {


        LinkedList<ProgressResponseBody.ProgressListener> progressListeners = listenerMap.get(url);
        if (progressListeners == null) {
            progressListeners = new LinkedList<>();
        }
        progressListeners.add(listener);
        listenerMap.put(url, progressListeners);
    }


    /**
     * 移除监听器
     *
     * @param url      tag
     * @param listener
     */
    public void removeTaskListener(String url, ProgressResponseBody.ProgressListener listener) {

        LinkedList<ProgressResponseBody.ProgressListener> progressListeners = listenerMap.get(url);
        if (progressListeners != null) {
            progressListeners.remove(listener);
        }

    }

    /***
     * 移除一个下载任务
     *
     * @param item 下载对象的bean
     * @return 如果移除成功返回true
     */
    public synchronized boolean removeTask(DownloadItem item) {
        if (queue.contains(item)) {
            return queue.remove(item);
        } else {
            //检查正在下载队列是否有这个bean 然后移除他;
            if (map.containsKey(item.getUrl())) {
                ProgressDownloader progressDownloader = map.get(item.getUrl());
                progressDownloader.cancle();
                return true;
            }
        }
        return false;
    }


}
